package remote.containers
{
	import flash.display.DisplayObject;
	
	import remote.core.ISelectableList;
	import remote.events.ChildExistenceChangedEvent;
	
	
	/**
	 * 导航容器
	 * @author 银魂飞雪
	 * @createDate 2011-3-29
	 */
	public class ViewStack extends Container implements ISelectableList
	{
		private var _selectedIndex:int = -1;
		public function ViewStack()
		{
			super();
			this.addEventListener(ChildExistenceChangedEvent.CHILD_ADD, childAddHandler);
			this.addEventListener(ChildExistenceChangedEvent.CHILD_REMOVE, childRemoveHandler);
		}
		
		private function updateSelected(newIndex:int):void
		{
			var oldIndex:int = _selectedIndex;
			if(numChildren == 0)
				_selectedIndex = -1;
			else if(numChildren == 1)
				_selectedIndex = 0;
			else
			{
				if(newIndex < 0)
					newIndex = 0;
				if(newIndex > numChildren - 1)
					newIndex = numChildren - 1;
				if(_selectedIndex != newIndex)
					_selectedIndex = newIndex;
			}
			if(oldIndex != _selectedIndex)
			{
				hide(oldIndex);
				show(_selectedIndex);
			}
		}
		
		private function hide(index:int):void
		{
			if(index >= 0 && index < numChildren)
			{
				(getItemAt(index) as DisplayObject).visible = false;	
			}
		}
		
		private function show(index:int):void
		{
			if(index >= 0 && index < numChildren)
			{
				(getItemAt(index) as DisplayObject).visible = true;	
			}
		}
		
		private function childAddHandler(e:ChildExistenceChangedEvent):void
		{
			e.relatedObject.visible = false;
			if(selectedIndex == -1 || getItemIndex(e.relatedObject) <= selectedIndex)
				updateSelected(_selectedIndex + 1);
		}
		private function childRemoveHandler(e:ChildExistenceChangedEvent):void
		{
			var index:int = getItemIndex(e.relatedObject);
			var newSelectedIndex:int;
			if(index < selectedIndex)
				_selectedIndex--;
			else if(index == selectedIndex)
			{
				if(length == 1)
				{
					_selectedIndex = -1;
				}
				else if(selectedIndex == length - 1)
				{
					this.show(0);
					_selectedIndex = 0;
				}
				else
					this.show(_selectedIndex + 1);
			}
			
		}
		
		/**
		 * @inheritDoc 
		 * 
		 */	
		public function get selectedIndex():int
		{
			return _selectedIndex;
		}
		
		public function set selectedIndex(value:int):void
		{
			if(value != selectedIndex)
			{
				updateSelected(value);
			}
		}
		/**
		 * @inheritDoc 
		 * 
		 */	
		public function get selectedItem():Object
		{
			if(selectedIndex == -1)
				return null;
			return getItemAt(selectedIndex);
		}
		
		public function set selectedItem(item:Object):void
		{
			if(contains(item as DisplayObject))
				selectedIndex = getItemIndex(item);
		}
		/**
		 * @inheritDoc 
		 * 
		 */	
		public function get length():int
		{
			return numChildren;
		}
		/**
		 * @inheritDoc 
		 * 
		 */	
		public function addItem(item:Object):void
		{
			super.addChild(item as DisplayObject);
		}
		/**
		 * @inheritDoc 
		 * 
		 */	
		public function addItemAt(item:Object, index:int):void
		{
			super.addChildAt(item as DisplayObject, index);
		}
		/**
		 * @inheritDoc 
		 * 
		 */	
		public function removeItem(item:Object):Object
		{
			return super.removeChild(item as DisplayObject);
		}
		/**
		 * @inheritDoc 
		 * 
		 */	
		public function removeItemAt(index:int):Object
		{
			return super.removeChildAt(index);
		}
		/**
		 * @inheritDoc 
		 * 
		 */	
		public function getItemAt(index:int):Object
		{
			return super.getChildAt(index);
		}
		/**
		 * @inheritDoc 
		 * 
		 */	
		public function getItemIndex(item:Object):int
		{
			return super.getChildIndex(item as DisplayObject);
		}
		/**
		 * @inheritDoc 
		 * 
		 */	
		public function removeAll():void
		{
			this.removeAllChildren();
			this.updateSelected(-1);
		}
		/**
		 * @inheritDoc 
		 * 
		 */	
		public function setItemAt(item:Object, index:int):Object
		{
			if(contains(item as DisplayObject) && index >= 0 && index < numChildren)
			{
				super.setChildIndex(item as DisplayObject, index);
				_selectedIndex = index;
				return item;
			}
			return null;
		}
		/**
		 * @inheritDoc 
		 * 
		 */	
		public function toArray():Array
		{
			return this.getChildren();
		}
	}
}